#include "spreadsheetwindow.h"
#include "spreadsheetundocommand.h"
#include "ui_spreadsheetwindow.h"

SpreadsheetWindow::SpreadsheetWindow(QWidget *parent)
    : QMainWindow(parent)
    ,ui(new Ui::SpreadSheetWindow)//初始化ui
    ,settings("MyCompany", "SpreadSheet")// 初始化QSettings
    ,copyBuffer()// 复制缓冲区
    ,bufferTopLeft()// 复制区域的左上角坐标
{
    initUI();//初始化UI
    setStatus();//设置状态栏信息
    spreadsheetmodel = new SpreadsheetModel(40, 30, this);// 创建模型（初始 xx行 xx列）
    ui->spreadsheetview->setModel(spreadsheetmodel);//获取 UI 中的视图 绑定模型到视图

    clipboard = QApplication::clipboard();// 初始化剪贴板监控
    createPasteOptionMenu();//初始化粘贴子菜单
    createConditionalReplaceMenu();//初始化条件粘贴子菜单

    initConnections();//连接信号槽
    registerFileAssociation();// 添加首次运行检查 改变.sheet文件图标
    // 自动加载上次打开的文件
    QString lastFile = settings.value("lastFile").toString();
    if (!lastFile.isEmpty() && QFile::exists(lastFile)) {
        loadFile(lastFile);
    }
}

//析构函数
SpreadsheetWindow::~SpreadsheetWindow()
{
    delete ui; // 释放UI资源
}

//初始化UI
void SpreadsheetWindow::initUI()
{
    ui->setupUi(this);//加载ui文件
    //调整视图默认大小
    resize(1280, 800);
    setWindowTitle("SpreadSheet[*]"); // 支持修改标记
}

//设置状态栏信息
void SpreadsheetWindow::setStatus()
{
    // 设置状态提示
    ui->actionNew->setStatusTip(tr("创建新的SpreadSheet表格文件(Ctrl+C)"));
    ui->actionOpen->setStatusTip(tr("打开现有的SpreadSheet表格文件(Ctrl+V)"));
    ui->actionSave->setStatusTip(tr("保存当前SpreadSheet表格到磁盘 (Ctrl+S)"));
    ui->actionSaveAs->setStatusTip(tr("另存为新的表格文件(Ctrl+Shift+S)"));

    ui->actionCopy->setStatusTip(tr("复制选中的单元格内容到剪贴板 (Ctrl+C)"));
    ui->actionPaste->setStatusTip(tr("从剪贴板粘贴数据到当前选区 (Ctrl+V)"));
    ui->actionCut->setStatusTip(tr("剪切选中的单元格内容到剪贴板 (Ctrl+X)"));
    ui->actionClear->setStatusTip(tr("清除选中单元格的内容 (Delete)"));

    ui->actionUndo->setStatusTip(tr("撤销上一步操作 (Ctrl+Z)"));
    ui->actionRedo->setStatusTip(tr("重做被撤销的操作 (Ctrl+Y)"));

    ui->actionAbout->setStatusTip(tr("显示程序信息和版权声明(Ctrl+H)"));
    ui->actionExit->setStatusTip(tr("退出程序 (Alt+F4)"));

}

//连接信号槽
void SpreadsheetWindow::initConnections()
{
    /*行列扩展*/
    connect(ui->spreadsheetview, &SpreadsheetView::scrolledToBottom,this,&SpreadsheetWindow::addNewRow);// 底部信号连接行扩展
    connect(ui->spreadsheetview, &SpreadsheetView::scrolledToRight,this,&SpreadsheetWindow::addNewCol);// 最右部信号连接列扩展

    /*文件管理*/
    connect(ui->actionNew, &QAction::triggered, this, &SpreadsheetWindow::newFile);//新建
    connect(ui->actionOpen, &QAction::triggered, this, &SpreadsheetWindow::openFile);//打开
    connect(ui->actionSave, &QAction::triggered, this, &SpreadsheetWindow::saveFile);//保存
    connect(ui->actionSaveAs, &QAction::triggered, this, &SpreadsheetWindow::saveAsFile);//另存为
    connect(spreadsheetmodel, &QAbstractItemModel::dataChanged, this, [this]() {setWindowModified(true);});//修改记录

    /*UI交互*/
    connect(ui->actionExit,&QAction::triggered,this,&QMainWindow::close); //关闭程序
    connect(ui->spreadsheetview, &SpreadsheetView::requestContextMenu,  this, &SpreadsheetWindow::showContextMenu);//右键菜单
    connect(ui->actionAbout,&QAction::triggered,this,&SpreadsheetWindow::aboutSpreadSheet);

    /*撤销与重做*/
    // 手动连接信号槽（核心功能连接）
    connect(ui->actionUndo, &QAction::triggered,  spreadsheetmodel->m_undoStack, &QUndoStack::undo);  // 当撤销动作被触发时调用撤销堆栈的undo()方法
    connect(ui->actionRedo, &QAction::triggered,  spreadsheetmodel->m_undoStack, &QUndoStack::redo);  // 当重做动作被触发时调用撤销堆栈的redo()方法
    // 更新动作状态（动态启用/禁用）
    connect(spreadsheetmodel->m_undoStack, &QUndoStack::canUndoChanged,  ui->actionUndo, &QAction::setEnabled);  // 当堆栈的"可撤销"状态变化时自动更新撤销动作的启用状态
    connect(spreadsheetmodel->m_undoStack, &QUndoStack::canRedoChanged,  ui->actionRedo, &QAction::setEnabled);  // 当堆栈的"可重做"状态变化时自动更新重做动作的启用状态
    // 初始化状态（设置初始启用状态）
    ui->actionUndo->setEnabled(spreadsheetmodel->m_undoStack->canUndo()); // 根据当前堆栈状态设置撤销按钮
    ui->actionRedo->setEnabled(spreadsheetmodel->m_undoStack->canRedo()); // 根据当前堆栈状态设置重做按钮

    /*复制粘贴剪切*/
    connect(ui->actionCopy,&QAction::triggered,this,&SpreadsheetWindow::copySelection);//复制
    connect(ui->actionPaste,&QAction::triggered,this,&SpreadsheetWindow::pasteToSelection);//粘贴
    connect(ui->actionCut,&QAction::triggered,this,&SpreadsheetWindow::cutSelection);//剪切
    connect(clipboard, &QClipboard::dataChanged, this, &SpreadsheetWindow::updateCopyBufferFromClipboard);// 初始化剪贴板监控
    //条件粘贴
    connect(pasteOptionMenu->actions().at(0), &QAction::triggered, this, &SpreadsheetWindow::pasteReplace);//替换
    connect(pasteOptionMenu->actions().at(1), &QAction::triggered, this, &SpreadsheetWindow::pasteAdd);//相加
    connect(pasteOptionMenu->actions().at(2), &QAction::triggered, this, &SpreadsheetWindow::pasteSubtract);//相减
    connect(conditionalReplaceMenu->actions().at(0), &QAction::triggered, this, &SpreadsheetWindow::pasteReplaceWhenGreater);//大于原数替换
    connect(conditionalReplaceMenu->actions().at(1), &QAction::triggered, this, &SpreadsheetWindow::pasteReplaceWhenLess);//小于原数替换

    /*插入删除*/
    connect(ui->actionInsertRow,&QAction::triggered,this,&SpreadsheetWindow::insertRow);//插入行
    connect(ui->actionInsertCol,&QAction::triggered,this,&SpreadsheetWindow::insertCol);//插入列
    connect(ui->actionDeleteRow,&QAction::triggered,this,&SpreadsheetWindow::deleteRow);//删除行
    connect(ui->actionDeleteCol,&QAction::triggered,this,&SpreadsheetWindow::deleteCol);//删除列
    connect(ui->actionClear,&QAction::triggered,this,&SpreadsheetWindow::clearContents);//清除单元格内容
    connect(ui->spreadsheetview, &SpreadsheetView::clearSelectedCells,this,&SpreadsheetWindow::clearContents);//按键清除内容

    /* 命令栈*/
    // 连接模型的数据变化信号
    connect(spreadsheetmodel, &SpreadsheetModel::dataChangedEx,this, [this]
            (const QModelIndex &index,const QVariant &oldValue,const QVariant &newValue){
                // 当数据即将改变时执行的lambda函数
                // 创建并压入撤销命令到堆栈
                spreadsheetmodel->m_undoStack->push(new SpreadsheetUndoCommand(spreadsheetmodel,index,oldValue,newValue));
            });

    /*排序*/
    connect(ui->actionsortColAsc,&QAction::triggered,this,&SpreadsheetWindow::sortCurrentColumnAscending);
    connect(ui->actionsortColDesc,&QAction::triggered,this,&SpreadsheetWindow::sortCurrentColumnDescending);
    connect(ui->actionsortRowAsc,&QAction::triggered,this,&SpreadsheetWindow::sortCurrentRowAscending);
    connect(ui->actionsortRowDesc,&QAction::triggered,this,&SpreadsheetWindow::sortCurrentRowDescending);
    connect(ui->actionCaseSensitive,&QAction::toggled,this,&SpreadsheetWindow::toggleCaseSensitiveSort);

    /*统计计算*/
    connect(ui->actionSum,&QAction::triggered,this,&SpreadsheetWindow::calculateSum);
    connect(ui->actionAverage,&QAction::triggered,this,&SpreadsheetWindow::calculateAverage);
    connect(ui->actionMax,&QAction::triggered,this,&SpreadsheetWindow::calculateMax);
    connect(ui->actionMin,&QAction::triggered,this,&SpreadsheetWindow::calculateMin);

    /*公式计算*/
    connect(ui->spreadsheetview->selectionModel(), &QItemSelectionModel::selectionChanged,
            this, &SpreadsheetWindow::updateIndexLabel);// 单元格选择变化使索引显示变化
    connect(ui->spreadsheetview->selectionModel(), &QItemSelectionModel::selectionChanged,
            this, &SpreadsheetWindow::updateLineEditFromSelection);// 单元格选择变化 显示编辑栏内容
    connect(ui->lineEditFormula, &QLineEdit::editingFinished,
            this, &SpreadsheetWindow::updateCellFromLineEdit);// 编辑栏编辑后 更新单元格内容
    connect(spreadsheetmodel, &QAbstractItemModel::dataChanged,
            this, &SpreadsheetWindow::updateLineEditFromSelection);//单元格内容变化 更新编辑栏
    connect(ui->actionFSum,&QAction::triggered,this,&SpreadsheetWindow::insertSumFormula);//选择SUM函数
    connect(ui->actionFAverage,&QAction::triggered,this,&SpreadsheetWindow::insertAverageFormula);//选择AVERAGE函数
    connect(ui->actionFMax,&QAction::triggered,this,&SpreadsheetWindow::insertMaxFormula);//选择MAX函数
    connect(ui->actionFMin,&QAction::triggered,this,&SpreadsheetWindow::insertMinFormula);//选择MIN函数
    connect(ui->actionCustomize,&QAction::triggered,this,&SpreadsheetWindow::TypeFormula);//键入公式
}

/*文件管理*/
// 设置当前文件并更新最近文件
void SpreadsheetWindow::setCurrentFile(const QString &fileName)
{
    currentFile = fileName;
    setWindowModified(false);

    if (!fileName.isEmpty()) {
        settings.setValue("lastFile", fileName);  // 记住当前文件
    }
}
//修改sheet文件的图标
bool SpreadsheetWindow::registerFileAssociation()
{
    // 检查是否已正确注册（避免重复处理）
    QSettings regCheck("HKEY_CLASSES_ROOT\\.sheet", QSettings::NativeFormat);
    QString currentHandler = regCheck.value("Default").toString();

    //程序路径 绝对路径
    QString appPath = QDir::toNativeSeparators(QCoreApplication::applicationFilePath());

    // 如果 .sheet 已关联到 SpreadsheetFile，且打开命令正确，则直接返回
    if (currentHandler == "SpreadsheetFile") {
        QSettings typeCheck("HKEY_CLASSES_ROOT\\SpreadsheetFile\\shell\\open\\command", QSettings::NativeFormat);
        QString currentCommand = typeCheck.value("Default").toString();
        QString expectedCommand = QString("\"%1\" \"%2\"").arg(appPath, "%1");
        if (currentCommand == expectedCommand) {
            // QMessageBox::information(this, "Info", "File association is already registered correctly.");
            return true; // 已正确配置，无需重复处理
        }
    }

    // 检查管理员权限
    if (!IsUserAnAdmin()) {
        QMessageBox::warning(this, "文件关联错误", "请以管理员身份运行。");
        return false;
    }

    // 提取图标到临时目录
    QString iconPath = extractIconToTemp();
    if (iconPath.isEmpty()) {
        return false;
    }

    // 注册 .sheet 扩展名
    // 系统知道 .sheet 文件应由 SpreadsheetFile 类型的程序处理
    QSettings reg("HKEY_CLASSES_ROOT\\.sheet", QSettings::NativeFormat);
    reg.setValue("Default", "SpreadsheetFile");
    // 注册文件类型 SpreadsheetFile
    QSettings regType("HKEY_CLASSES_ROOT\\SpreadsheetFile", QSettings::NativeFormat);
    // 在资源管理器中显示的文件类型描述（如“Spreadsheet Document”）
    regType.setValue("Default", "Spreadsheet Document");
    // 设置 .sheet 文件的默认图标路径（需用引号包裹路径以防空格）
    regType.setValue("DefaultIcon/Default", QString("\"%1\"").arg(iconPath));
    // 定义双击文件时的执行命令：
    regType.setValue("shell/open/command/Default", QString("\"%1\" \"%2\"").arg(appPath, "%1"));
    // 刷新系统图标缓存
    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
    QMessageBox::information(this, "文件关联成功", "文件关联已注册！!");
    return true;
}
//提取 .ico 文件到临时目录
QString SpreadsheetWindow::extractIconToTemp()
{
    // 获取临时目录路径
    QString tempDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    QString iconPath = tempDir + "/spreadsheet.ico";
    // 如果文件已存在，则跳过提取
    if (QFile::exists(iconPath)) {
        return iconPath;
    }
    // 从资源文件复制到临时目录
    QFile iconFile(":/new/prefix1/spreadsheet.ico");
    if (iconFile.copy(iconPath)) {
        QFile::setPermissions(iconPath, QFile::ReadOwner | QFile::WriteOwner);
        return iconPath;
    } else {
        qWarning() << "Failed to extract icon:" << iconFile.errorString();
        return QString();
    }
}
// 加载文件
void SpreadsheetWindow::loadFile(const QString &fileName)
{
    if (!QFile::exists(fileName)) {
        return;  // 文件不存在则不做任何操作
    }
    QFile file(fileName);
    // QIODevice::ReadOnly：只读模式。
    if (!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(this, tr("Spreadsheet"),
                             tr("Cannot read file %1:\n%2.")
                                 .arg(QDir::toNativeSeparators(fileName),file.errorString()));
        return;
    }
    QDataStream in(&file);
    in.setVersion(QDataStream::Qt_5_15);
    // 读取文件头验证格式
    quint32 magic;
    in >> magic;
    if (magic != 0x53504854) { // "SPHT"的十六进制
        QMessageBox::warning(this, tr("Spreadsheet"),
                             tr("The file is not a Spreadsheet file."));
        return;
    }
    // 读取数据
    spreadsheetmodel->clear();
    in>> *spreadsheetmodel;
    //清空命令栈
    spreadsheetmodel->m_undoStack->clear();

    currentFile = fileName;
    setWindowTitle(QFileInfo(fileName).fileName() + "[*]");
    setWindowModified(false);
    setCurrentFile(fileName);  // 记住成功加载的文件
}
// 实际保存到文件
bool SpreadsheetWindow::saveToFile(const QString &fileName)
{
    QFile file(fileName);
    // 以只写模式打开文件，失败时提示用户
    if (!file.open(QIODevice::WriteOnly)) {
        QMessageBox::warning(this, tr("Spreadsheet"),
                             tr("无法写入文件 %1:\n%2.")
                                 .arg(QDir::toNativeSeparators(fileName),file.errorString()));
        return false;
    }
    // 配置数据流
    QDataStream out(&file);
    out.setVersion(QDataStream::Qt_5_15);
    // 写入文件头标识
    out << quint32(0x53504854); // "SPHT"的十六进制
    // 直接使用 operator<< 序列化整个模型
    out << *spreadsheetmodel;

    currentFile = fileName;
    setWindowTitle(QFileInfo(fileName).fileName() + "[*]");
    // [*] 是 Qt 的未修改标记（setWindowModified(false) 后会隐藏 *）。
    setWindowModified(false);
    return true;
}

/*统计计算*/
// 统计计算核心方法
QString SpreadsheetWindow::calculateSelection(SpreadsheetModel::StatType type)
{
    // 获取当前选择的计算模式（0=行，1=列，2=块）
    int method = ui->comboBoxCalMethod->currentIndex();

    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (selected.isEmpty()) {
        return tr("错误：未选中数据");
    }

    // 获取首个选中单元格的位置（用于行/列模式）
    int refRow = selected.first().row();
    int refCol = selected.first().column();

    //用于统计计算
    QVector<double> values;

    // 按行模式（整行统计）
    if (method == 0) {
        int colCount = spreadsheetmodel->columnCount();
        for (int col = 0; col < colCount; ++col) {
            QModelIndex idx = spreadsheetmodel->index(refRow, col);
            bool ok;
            double val = idx.data().toDouble(&ok);
            if (ok) values.append(val);
        }
    }
    // 按列模式（整列统计）
    else if (method == 1) {
        int rowCount = spreadsheetmodel->rowCount();
        for (int row = 0; row < rowCount; ++row) {
            QModelIndex idx = spreadsheetmodel->index(row, refCol);
            bool ok;
            double val = idx.data().toDouble(&ok);
            if (ok) values.append(val);
        }
    }
    // 按块模式（原始选区）
    else {
        for (const QModelIndex &idx : selected) {
            bool ok;
            double val = idx.data().toDouble(&ok);
            if (ok) values.append(val);
        }
    }

    if (values.isEmpty()) {
        return tr("错误：无有效数值");
    }

    // 计算结果
    double result = 0;
    QString opName;
    QString prefix;

    switch (type) {
    case SpreadsheetModel::Sum:
        result = std::accumulate(values.begin(), values.end(), 0.0);
        opName = tr("合计");
        break;
    case SpreadsheetModel::Average:
        result = std::accumulate(values.begin(), values.end(), 0.0) / values.size();
        opName = tr("平均值");
        break;
    case SpreadsheetModel::Max:
        result = *std::max_element(values.begin(), values.end());
        opName = tr("最大值");
        break;
    case SpreadsheetModel::Min:
        result = *std::min_element(values.begin(), values.end());
        opName = tr("最小值");
        break;
    }

    QString colName;
    while (refCol>= 0) {
        colName.prepend(QChar('A' + (refCol % 26)));// 将数字转换为字母（A-Z）
        refCol = refCol/ 26 - 1;// 将数字转换为字母（A-Z）
    }

    // 生成结果前缀
    if (method == 0) {
        prefix = tr("行%1").arg(refRow + 1);
    } else if (method == 1) {
        prefix = tr("列%1").arg(colName);
    }

    return prefix.isEmpty() ? QString("%1: %2").arg(opName).arg(result)
                            : QString("%1 %2: %3").arg(prefix).arg(opName).arg(result);
}

/*单元格批量复制粘贴*/
//创建粘贴选项菜单
void SpreadsheetWindow::createPasteOptionMenu()
{
    pasteOptionMenu = new QMenu(this);
    pasteOptionMenu->addAction(tr("代替"), this, &SpreadsheetWindow::pasteReplace);
    pasteOptionMenu->addAction(tr("相加"), this, &SpreadsheetWindow::pasteAdd);
    pasteOptionMenu->addAction(tr("相减"), this, &SpreadsheetWindow::pasteSubtract);

    conditionalReplaceMenu = new QMenu(tr("按条件替换"), this);
    pasteOptionMenu->addMenu(conditionalReplaceMenu);
}
//创建按条件替换子菜单
void SpreadsheetWindow::createConditionalReplaceMenu()
{
    conditionalReplaceMenu->addAction(tr("粘贴大于原数时替换"), this, &SpreadsheetWindow::pasteReplaceWhenGreater);
    conditionalReplaceMenu->addAction(tr("粘贴小于原数时替换"), this, &SpreadsheetWindow::pasteReplaceWhenLess);
}
//根据选项实现粘贴动作
void SpreadsheetWindow::pasteWithOption(QAction* action)
{
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    // 检查是否有选中的项，如果没有则直接返回
    if (!selection->hasSelection())
        return;
    // 获取所有被选中的索引列表
    QModelIndexList indexes = selection->selectedIndexes();
    // 获取当前选中单元格
    QModelIndex current=indexes.first();

    // QModelIndex current = ui->spreadsheetview->currentIndex();
    if (!current.isValid())
        return;

    // 确定粘贴起始位置
    int startRow = current.row();
    int startCol = current.column();

    // 计算相对偏移量
    int rowOffset = startRow - bufferTopLeft.y();
    int colOffset = startCol - bufferTopLeft.x();

    // 收集所有修改
    QMap<QModelIndex, QPair<QVariant, QVariant>> changes;

    // 开始批量操作
    spreadsheetmodel->beginModelReset();

    // 遍历缓冲区并粘贴数据
    for (int row = 0; row < copyBuffer.size(); ++row) {
        for (int col = 0; col < copyBuffer[row].size(); ++col) {
            // 计算目标单元格位置
            int targetRow = row + bufferTopLeft.y() + rowOffset;
            int targetCol = col + bufferTopLeft.x() + colOffset;
            // 边界检查
            if (targetRow < spreadsheetmodel->rowCount() &&
                targetCol < spreadsheetmodel->columnCount()) {

                QModelIndex index = spreadsheetmodel->index(targetRow, targetCol);
                QVariant oldValue = spreadsheetmodel->data(index, Qt::EditRole);
                QVariant newValue = copyBuffer[row][col];

                if (action == pasteOptionMenu->actions().at(0)) { // 代替
                    // 直接使用新值
                } else if (action == pasteOptionMenu->actions().at(1)) { // 相加
                    bool ok1, ok2;
                    double oldVal = oldValue.toDouble(&ok1);
                    double newVal = newValue.toDouble(&ok2);
                    if (ok1 && ok2) {
                        newValue = oldVal + newVal;
                    }
                } else if (action == pasteOptionMenu->actions().at(2)) { // 相减
                    bool ok1, ok2;
                    double oldVal = oldValue.toDouble(&ok1);
                    double newVal = newValue.toDouble(&ok2);
                    if (ok1 && ok2) {
                        newValue = oldVal - newVal;
                    }
                } else if (action == pasteOptionMenu->actions().at(3)) { // 按条件替换
                    // 这里可以实现按条件替换的逻辑，例如根据值的大小、类型等进行替换
                    // 示例：如果旧值大于 0，则替换为新值
                    if (oldValue.toDouble() > 0) {
                        // newValue = newValue;
                    } else {
                        newValue = oldValue;
                    }
                }

                if (oldValue != newValue) {
                    changes.insert(index, qMakePair(oldValue, newValue));
                }
            }
        }
    }
    if (!changes.isEmpty()) {
        // 创建批量撤销命令
        QUndoCommand* batchCommand = new SpreadsheetUndoCommand(spreadsheetmodel, changes);
        spreadsheetmodel->m_undoStack->push(batchCommand);
    }
    // 结束批量操作
    spreadsheetmodel->endModelReset();
}
//按条件粘贴
void SpreadsheetWindow::pasteConditionalReplace()
{
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    // 检查是否有选中的项，如果没有则直接返回
    if (!selection->hasSelection())
        return;
    // 获取所有被选中的索引列表
    QModelIndexList indexes = selection->selectedIndexes();
    // 获取当前选中单元格
    QModelIndex current=indexes.first();

    if (!current.isValid())
        return;

    // 确定粘贴起始位置
    int startRow = current.row();
    int startCol = current.column();

    // 计算相对偏移量
    int rowOffset = startRow - bufferTopLeft.y();
    int colOffset = startCol - bufferTopLeft.x();

    // 收集所有修改
    QMap<QModelIndex, QPair<QVariant, QVariant>> changes;

    // 开始批量操作
    spreadsheetmodel->beginModelReset();

    // 遍历缓冲区并粘贴数据
    for (int row = 0; row < copyBuffer.size(); ++row) {
        for (int col = 0; col < copyBuffer[row].size(); ++col) {
            // 计算目标单元格位置
            int targetRow = row + bufferTopLeft.y() + rowOffset;
            int targetCol = col + bufferTopLeft.x() + colOffset;
            // 边界检查
            if (targetRow < spreadsheetmodel->rowCount() &&
                targetCol < spreadsheetmodel->columnCount()) {

                QModelIndex index = spreadsheetmodel->index(targetRow, targetCol);
                QVariant oldValue = spreadsheetmodel->data(index, Qt::EditRole);
                QVariant newValue = copyBuffer[row][col];

                // 自定义条件替换逻辑
                if (!customReplaceCondition.isEmpty()) {
                    // 这里可以根据自定义条件进行替换，例如根据条件字符串进行判断
                    if (oldValue.toString().contains(customReplaceCondition)) {
                        // newValue = newValue;
                    } else {
                        newValue = oldValue;
                    }
                }

                if (oldValue != newValue) {
                    changes.insert(index, qMakePair(oldValue, newValue));
                }
            }
        }
    }
    if (!changes.isEmpty()) {
        // 创建批量撤销命令
        QUndoCommand* batchCommand = new SpreadsheetUndoCommand(spreadsheetmodel, changes);
        spreadsheetmodel->m_undoStack->push(batchCommand);
    }
    // 结束批量操作
    spreadsheetmodel->endModelReset();
}

// 槽函数
/*行列扩展*/
// 添加新行
void SpreadsheetWindow::addNewRow()
{
    if (!spreadsheetmodel) return;  // 确保模型存在
    // 获取当前模型的行数
    int rowCount = spreadsheetmodel->rowCount();
    // 在模型末尾插入行
    spreadsheetmodel->insertRows(rowCount,5);
}
// 添加新列
void SpreadsheetWindow::addNewCol()
{
    if (!spreadsheetmodel) return;  // 确保模型存在
    int colCount=spreadsheetmodel->columnCount();
    spreadsheetmodel->insertColumn(colCount);
}

/*文件管理*/
// 新建文件
void SpreadsheetWindow::newFile()
{
    if (maybeSave()) {// 检查是否需要保存旧文件
        spreadsheetmodel->clear();// 清空数据

        spreadsheetmodel->m_undoStack->clear();// 清除撤销栈

        spreadsheetmodel->setRowCount(40);
        spreadsheetmodel->setColumnCount(30);
        currentFile.clear();// 清空当前文件名
        setWindowTitle(" 新建 SpreadSheet[*]");// 设置标题（含[*]占位符）
        setWindowModified(false);// 标记为未修改（不显示*）
    }
}
// 打开文件
void SpreadsheetWindow::openFile()
{
    if (maybeSave()) {
        QString fileName = QFileDialog::getOpenFileName(this,
                                                        tr("打开 Spreadsheet"), "",
                                                        tr("Spreadsheet 文件 (*.sheet);;所有文件 (*)"));

        if (!fileName.isEmpty()) {
            spreadsheetmodel->m_undoStack->clear();// 加载新文件前清除撤销栈
            loadFile(fileName);
        }
    }
}
// 保存文件
void SpreadsheetWindow::saveFile()
{
    if (currentFile.isEmpty()) {
        saveAsFile();
    } else {
        saveToFile(currentFile);
    }
}
// 另存为
void SpreadsheetWindow::saveAsFile()
{
    // 弹出文件保存对话框
    QString fileName = QFileDialog::getSaveFileName(this,
                                                    tr("Save Spreadsheet As"), "",
                                                    tr("Spreadsheet Files (*.sheet);;All Files (*)"));
    // 如果用户点击了“取消”或关闭对话框，
    // fileName 会为空字符串，此时直接返回，不执行保存
    if (fileName.isEmpty())
        return;
    // 自动补全文件后缀
    // Qt::CaseInsensitive：表示忽略大小写匹配（如 .SHEET 和 .sheet 均视为合法后缀）
    if (!fileName.endsWith(".sheet", Qt::CaseInsensitive))
        fileName += ".sheet";

    saveToFile(fileName);
}
// 检查是否需要保存
bool SpreadsheetWindow::maybeSave()
{
    // isWindowModified() 判断窗口内容是否被修改（即是否有未保存的更改）。
    // 如果 未被修改（返回 false），直接返回 true，表示无需保存，可以继续后续操作。
    // 如果 已被修改（返回 true），进入下一步提示用户。
    if (!isWindowModified())
        return true;

    QMessageBox::StandardButton ret;
    ret = QMessageBox::warning(this, "Spreadsheet",
                               tr("文档已被修改.\n"
                                  "是否要保存更改?"),
                               QMessageBox::Save | QMessageBox::Discard
                                   | QMessageBox::Cancel);// 按钮选项

    if (ret == QMessageBox::Save) // 用户点击“保存”
        saveFile();
    else if (ret == QMessageBox::Cancel)
        return false;// 用户点击“取消”

    return true;// 用户点击“保存”或“放弃”
}

/*单元格批量复制粘贴*/
// 实现复制功能
void SpreadsheetWindow::copySelection()
{
    // 获取spreadsheetview的当前选择模型，用于管理视图中的选择项
    // selectionModel() 返回该视图的当前选择模型，用于查询：哪些单元格被选中（selectedIndexes()）
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    // 检查是否有选中的项，如果没有则直接返回
    if (!selection->hasSelection())
        return;
    // 获取所有被选中的索引列表
    QModelIndexList indexes = selection->selectedIndexes();
    if (indexes.isEmpty()){
        //如果索引列表为空则直接返回
        qDebug() << "Empty selection";
        return;
    }

    // 确定选中区域的范围
    int minRow = INT_MAX, maxRow = 0;
    int minCol = INT_MAX, maxCol = 0;
    // 遍历所有选中的索引
    for (auto it = indexes.constBegin(); it != indexes.constEnd(); ++it) {
        const QModelIndex &index = *it;
        minRow = qMin(minRow, index.row());
        maxRow = qMax(maxRow, index.row());
        minCol = qMin(minCol, index.column());
        maxCol = qMax(maxCol, index.column());
    }

    // 将选中区域的左上角坐标(最小列号,最小行号)保存到bufferTopLeft
    bufferTopLeft = QPoint(minCol, minRow);
    // 清空复制缓冲区
    copyBuffer.clear();
    copyBuffer.reserve(maxRow - minRow + 1);

    //生成 TCV 格式的文本（Excel 兼容） 制表符间隔
    QString tsvText;

    // 将选中区域的数据存入缓冲区
    // 从最小行到最大行循环
    for (int row = minRow; row <= maxRow; ++row) {
        QVector<QVariant> rowData;//创建一个QVariant向量用于存储一行数据
        rowData.reserve(maxCol - minCol + 1);
        QStringList tsvRow;

        // 从最小列到最大列循环
        for (int col = minCol; col <= maxCol; ++col) {
            QModelIndex index = spreadsheetmodel->index(row, col);
            QString cellText = spreadsheetmodel->data(index, Qt::DisplayRole).toString();

            // TSV 格式：直接添加单元格内容（不包裹双引号）
            tsvRow << cellText;
            // 获取该单元格的显示数据并添加到行数据中
            rowData.append(cellText);
        }
        tsvText += tsvRow.join("\t") + "\r\n";  // 制表符分隔 + Windows 换行
        // 将一行数据添加到复制缓冲区
        copyBuffer.append(rowData);
    }

    // 将数据存入剪贴板（支持 CSV 格式，可粘贴到 Excel）
    QClipboard *clipboard = QApplication::clipboard();// 获取应用程序剪贴板
    if (!clipboard) {
        qWarning() << "Failed to access clipboard";
        return;
    }
    QMimeData *mimeData = new QMimeData();// 创建新的MIME数据对象
    mimeData->setText(tsvText.trimmed());  // 存入剪贴板文本 纯文本格式
    mimeData->setData("text/tsv", tsvText.toUtf8());  // CSV 格式
    clipboard->setMimeData(mimeData);      // 设置剪贴板数据
}
// 粘贴到选中区域
void SpreadsheetWindow::pasteToSelection()
{
    // 检查缓冲区是否为空
    if (copyBuffer.isEmpty()){
        return;
    }
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    // 检查是否有选中的项，如果没有则直接返回
    if (!selection->hasSelection())
        return;
    // 获取所有被选中的索引列表
    QModelIndexList indexes = selection->selectedIndexes();
    if (indexes.isEmpty()){
        //如果索引列表为空则直接返回
        qDebug() << "Empty selection";
        return;
    }
    // 获取当前选中单元格
    QModelIndex current =indexes.first();
    // QModelIndex current =ui->spreadsheetview->currentIndex();
    if (!current.isValid())
        return;

    // 判断选中区域是否为空
    bool isSelectionEmpty = true;
    for (const auto& index : indexes) {
        QVariant value = spreadsheetmodel->data(index, Qt::EditRole);
        if (!value.isNull() && !value.toString().isEmpty()) {
            isSelectionEmpty = false;
            break;
        }
    }

    //如果不为空
    if (isSelectionEmpty) {
        // 直接使用代替粘贴选项
        pasteWithOption(pasteOptionMenu->actions().at(0));
    } else {
        // 显示粘贴选项菜单
        QPoint pos = ui->spreadsheetview->viewport()->mapToGlobal(ui->spreadsheetview->visualRect(current).topLeft());
        QAction* selectedAction = pasteOptionMenu->exec(pos);
        if (selectedAction) {
            pasteWithOption(selectedAction);
        }
    }
}
//实现大于原数替换
void SpreadsheetWindow::pasteReplaceWhenGreater()
{
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    // 检查是否有选中的项，如果没有则直接返回
    if (!selection->hasSelection())
        return;
    // 获取所有被选中的索引列表
    QModelIndexList indexes = selection->selectedIndexes();
    // 获取当前选中单元格
    QModelIndex current=indexes.first();

    if (!current.isValid())
        return;

    // 确定粘贴起始位置
    int startRow = current.row();
    int startCol = current.column();

    // 计算相对偏移量
    int rowOffset = startRow - bufferTopLeft.y();
    int colOffset = startCol - bufferTopLeft.x();

    // 收集所有修改
    QMap<QModelIndex, QPair<QVariant, QVariant>> changes;

    // 开始批量操作
    spreadsheetmodel->beginModelReset();

    // 遍历缓冲区并粘贴数据
    for (int row = 0; row < copyBuffer.size(); ++row) {
        for (int col = 0; col < copyBuffer[row].size(); ++col) {
            // 计算目标单元格位置
            int targetRow = row + bufferTopLeft.y() + rowOffset;
            int targetCol = col + bufferTopLeft.x() + colOffset;
            // 边界检查
            if (targetRow < spreadsheetmodel->rowCount() &&
                targetCol < spreadsheetmodel->columnCount()) {

                QModelIndex index = spreadsheetmodel->index(targetRow, targetCol);
                QVariant oldValue = spreadsheetmodel->data(index, Qt::EditRole);
                QVariant newValue = copyBuffer[row][col];

                // 尝试转换为数字
                bool ok1, ok2;
                double num1 = oldValue.toDouble(&ok1);
                double num2 = newValue.toDouble(&ok2);

                if (ok1 && ok2 && num2 > num1) {
                    if (oldValue != newValue) {
                        changes.insert(index, qMakePair(oldValue, newValue));
                    }
                }
            }
        }
    }
    if (!changes.isEmpty()) {
        // 创建批量撤销命令
        QUndoCommand* batchCommand = new SpreadsheetUndoCommand(spreadsheetmodel, changes);
        spreadsheetmodel->m_undoStack->push(batchCommand);
    }
    // 结束批量操作
    spreadsheetmodel->endModelReset();
}
//实现小于原数替换
void SpreadsheetWindow::pasteReplaceWhenLess()
{
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    // 检查是否有选中的项，如果没有则直接返回
    if (!selection->hasSelection())
        return;
    // 获取所有被选中的索引列表
    QModelIndexList indexes = selection->selectedIndexes();
    // 获取当前选中单元格
    QModelIndex current=indexes.first();

    if (!current.isValid())
        return;

    // 确定粘贴起始位置
    int startRow = current.row();
    int startCol = current.column();

    // 计算相对偏移量
    int rowOffset = startRow - bufferTopLeft.y();
    int colOffset = startCol - bufferTopLeft.x();

    // 收集所有修改
    QMap<QModelIndex, QPair<QVariant, QVariant>> changes;

    // 开始批量操作
    spreadsheetmodel->beginModelReset();

    // 遍历缓冲区并粘贴数据
    for (int row = 0; row < copyBuffer.size(); ++row) {
        for (int col = 0; col < copyBuffer[row].size(); ++col) {
            // 计算目标单元格位置
            int targetRow = row + bufferTopLeft.y() + rowOffset;
            int targetCol = col + bufferTopLeft.x() + colOffset;
            // 边界检查
            if (targetRow < spreadsheetmodel->rowCount() &&
                targetCol < spreadsheetmodel->columnCount()) {

                QModelIndex index = spreadsheetmodel->index(targetRow, targetCol);
                QVariant oldValue = spreadsheetmodel->data(index, Qt::EditRole);
                QVariant newValue = copyBuffer[row][col];

                // 尝试转换为数字
                bool ok1, ok2;
                double num1 = oldValue.toDouble(&ok1);
                double num2 = newValue.toDouble(&ok2);

                if (ok1 && ok2 && num2 < num1) {
                    if (oldValue != newValue) {
                        changes.insert(index, qMakePair(oldValue, newValue));
                    }
                }
            }
        }
    }
    if (!changes.isEmpty()) {
        // 创建批量撤销命令
        QUndoCommand* batchCommand = new SpreadsheetUndoCommand(spreadsheetmodel, changes);
        spreadsheetmodel->m_undoStack->push(batchCommand);
    }
    // 结束批量操作
    spreadsheetmodel->endModelReset();
}
//替换粘贴
void SpreadsheetWindow::pasteReplace()
{
    pasteWithOption(pasteOptionMenu->actions().at(0));
}
//相加粘贴
void SpreadsheetWindow::pasteAdd()
{
    pasteWithOption(pasteOptionMenu->actions().at(1));
}
//相减粘贴
void SpreadsheetWindow::pasteSubtract()
{
    pasteWithOption(pasteOptionMenu->actions().at(2));
}
// 剪切选中区域
void SpreadsheetWindow::cutSelection()
{
    copySelection(); // 先复制

    // 然后清空选中区域
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    QModelIndexList indexes = selection->selectedIndexes();

    // 收集所有修改
    QMap<QModelIndex, QPair<QVariant, QVariant>> changes;

    spreadsheetmodel->beginModelReset();

    for (auto it = indexes.constBegin(); it != indexes.constEnd(); ++it) {
        const QModelIndex &index = *it;
        QVariant oldValue = spreadsheetmodel->data(index, Qt::EditRole);//记录原来的数据
        if (!oldValue.isNull()) {
            changes.insert(index, qMakePair(oldValue, QVariant()));
        }
    }
    if (!changes.isEmpty()) {
        // 创建批量撤销命令
        QUndoCommand* batchCommand = new SpreadsheetUndoCommand(spreadsheetmodel, changes);
        // qDebug()<<"command";
        spreadsheetmodel->m_undoStack->push(batchCommand);
    }
    spreadsheetmodel->endModelReset();
}
// 剪贴板更新时的槽函数
void SpreadsheetWindow::updateCopyBufferFromClipboard()
{
    QString clipboardText = clipboard->text().replace("\r\n", "\n");
    if (clipboardText.isEmpty()) {
        copyBuffer.clear();
        return;
    }
    // 清空旧数据
    copyBuffer.clear();
    // 解析剪贴板数据
    QStringList rows = clipboardText.split("\n", Qt::SkipEmptyParts);
    for (const QString &row : rows) {
        QStringList cells = row.split("\t");
        QVector<QVariant> rowData;
        for (const QString &cell : cells) {
            rowData.append(cell.trimmed());
        }
        copyBuffer.append(rowData);
    }
}

/*插入删除*/
//插入行
void SpreadsheetWindow::insertRow()
{
    // 获取当前选择
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (!selected.isEmpty()) {
        // 在第一行选中的位置插入行
        int row = selected.first().row();
        // 然后创建并推送撤销命令
        spreadsheetmodel->m_undoStack->push(new InsertRowCommand(spreadsheetmodel, row));
    }
}
//插入列
void SpreadsheetWindow::insertCol()
{
    // 获取当前选择
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (!selected.isEmpty()) {
        // 在第一行选中的位置插入行
        int col = selected.first().column();
        // 然后创建并推送撤销命令
        spreadsheetmodel->m_undoStack->push(new InsertColumnCommand(spreadsheetmodel, col));
    }
}
//删除行
void SpreadsheetWindow::deleteRow()
{
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (!selected.isEmpty()) {
        int row = selected.first().row();
        spreadsheetmodel->m_undoStack->push(new DeleteRowCommand(spreadsheetmodel, row));
    }
}
//删除列
void SpreadsheetWindow::deleteCol()
{
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (!selected.isEmpty()) {
        int col = selected.first().column();
        spreadsheetmodel->m_undoStack->push(new DeleteColumnCommand(spreadsheetmodel, col));
    }
}
//清除单元格内容
void SpreadsheetWindow::clearContents()
{
    // 选中区域
    QItemSelectionModel *selection = ui->spreadsheetview->selectionModel();
    QModelIndexList indexes = selection->selectedIndexes();

    // 收集所有修改
    QMap<QModelIndex, QPair<QVariant, QVariant>> changes;

    spreadsheetmodel->beginModelReset();

    for (auto it = indexes.constBegin(); it != indexes.constEnd(); ++it) {
        const QModelIndex &index = *it;
        QVariant oldValue = spreadsheetmodel->data(index, Qt::EditRole);//记录原来的数据
        if (!oldValue.isNull()) {
            changes.insert(index, qMakePair(oldValue, QVariant()));
        }
    }
    if (!changes.isEmpty()) {
        // 创建批量撤销命令 命令压入栈则调用redo命令 用空内容设置单元格即清除
        QUndoCommand* batchCommand = new SpreadsheetUndoCommand(spreadsheetmodel, changes);
        // qDebug()<<"command";
        spreadsheetmodel->m_undoStack->push(batchCommand);
    }
    spreadsheetmodel->endModelReset();
}

/*排序*/
//按列升序
void SpreadsheetWindow::sortCurrentColumnAscending()
{
    // 确保视图有模型
    if (!ui->spreadsheetview->model()) {
        qDebug() << "错误：视图没有设置模型";
        return;
    }
    //获取当前视图中选定的单元格索引
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (current.isValid()) {
        spreadsheetmodel->m_undoStack->push(new SpreadsheetSortCommand(spreadsheetmodel,current.column(),Qt::AscendingOrder));
    }
}
//按列降序
void SpreadsheetWindow::sortCurrentColumnDescending()
{
    // 确保视图有模型
    if (!ui->spreadsheetview->model()) {
        qDebug() << "错误：视图没有设置模型";
        return;
    }
    //获取当前视图中选定的单元格索引
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (current.isValid()) {
        //压入命令栈
        spreadsheetmodel->m_undoStack->push(new SpreadsheetSortCommand(spreadsheetmodel,current.column(),Qt::DescendingOrder));
    }
}
//按行升序
void SpreadsheetWindow::sortCurrentRowAscending()
{
    // 确保视图有模型
    if (!ui->spreadsheetview->model()) {
        qDebug() << "错误：视图没有设置模型";
        return;
    }
    //获取当前视图中选定的单元格索引
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (current.isValid()) {
        spreadsheetmodel->m_undoStack->push(new SpreadsheetSortCommand(spreadsheetmodel,current.row(),Qt::AscendingOrder,false));
    }
}
//按行降序
void SpreadsheetWindow::sortCurrentRowDescending()
{
    // 确保视图有模型
    if (!ui->spreadsheetview->model()) {
        qDebug() << "错误：视图没有设置模型";
        return;
    }
    //获取当前视图中选定的单元格索引
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (current.isValid()) {
        spreadsheetmodel->m_undoStack->push(new SpreadsheetSortCommand(spreadsheetmodel,current.row(),Qt::DescendingOrder,false));
    }
}
//设置排序是否大小写敏感
void SpreadsheetWindow::toggleCaseSensitiveSort(bool enabled)
{
    //修改排序大小写敏感
    spreadsheetmodel->setCaseSensitiveSort(enabled);
}

/*统计计算*/
// 合计
void SpreadsheetWindow::calculateSum()
{
    QString result = calculateSelection(SpreadsheetModel::Sum); // 0=行,1=列
    showStatisticsResult(result);
}
// 平均
void SpreadsheetWindow::calculateAverage()
{
    QString result = calculateSelection(SpreadsheetModel::Average); // 0=行,1=列
    showStatisticsResult(result);
}
// 最大值
void SpreadsheetWindow::calculateMax()
{
    QString result = calculateSelection(SpreadsheetModel::Max); // 0=行,1=列
    showStatisticsResult(result);
}
// 最小值
void SpreadsheetWindow::calculateMin()
{
    QString result = calculateSelection(SpreadsheetModel::Min); // 0=行,1=列
    showStatisticsResult(result);
}
// 显示结果到编辑栏
void SpreadsheetWindow::showStatisticsResult(const QString &result)
{
    ui->lineEditCalculate->setText(result);
}

/*公式计算*/
// 当视图选择变化时更新编辑栏
void SpreadsheetWindow::updateLineEditFromSelection()
{
    //获取选择的单元格索引
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (selected.isEmpty()) {
        ui->lineEditFormula->clear();
        return;
    }
    // 获取单元格内容
    // 只显示第一个选中的单元格内容
    QModelIndex index = selected.first();
    // 获取原始公式（Qt::EditRole），而不是显示值（Qt::DisplayRole）
    QString formula = spreadsheetmodel->data(index, Qt::EditRole).toString();
    bool isformula=formula.startsWith("=");

    if(isformula)
    {
        ui->lineEditFormula->setText(formula);
    }
    else{
        ui->lineEditFormula->setText(spreadsheetmodel->data(index, Qt::DisplayRole).toString());
    }
}
// 当编辑栏内容变化时更新单元格
void SpreadsheetWindow::updateCellFromLineEdit()
{
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (selected.isEmpty()) return;

    QModelIndex index = selected.first();

    // 如果输入的是公式（以 '=' 开头），保存到 Qt::EditRole（原始数据）
    // 计算结果会自动在 handleCellChanged 中处理
    spreadsheetmodel->setData(index, ui->lineEditFormula->text(), Qt::EditRole);
}
//显示选择的单元格索引项
void SpreadsheetWindow::updateIndexLabel()
{
    //获取选择的单元格索引
    QModelIndexList selected = ui->spreadsheetview->selectionModel()->selectedIndexes();
    if (selected.isEmpty()) {
        ui->lineEditFormula->clear();
        return;
    }
    // 只显示第一个选中的单元格内容
    QModelIndex index = selected.first();
    // 获取列字母（A, B, C...）
    QString columnHeader = spreadsheetmodel->headerData(index.column(), Qt::Horizontal, Qt::DisplayRole).toString();
    // 行号从1开始（index.row()返回的是0-based，所以+1）
    QString rowHeader = QString::number(index.row() + 1);

    // 组合成 "A1" 格式
    QString cellIndex = columnHeader + rowHeader;
    //改变按钮的显示内容
    ui->pushButtonIndex->setText(cellIndex);
    //改变颜色
    ui->pushButtonIndex->setStyleSheet("QPushButton:disabled { color: #000000; }");
}
//选择SUM函数
void SpreadsheetWindow::insertSumFormula()
{
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (!current.isValid()) return;
    // 插入公式
    spreadsheetmodel->setData(current, "=SUM()", Qt::EditRole);
    // 进入编辑模式，光标定位到括号内
    ui->spreadsheetview->edit(current);
    QLineEdit *editor = qobject_cast<QLineEdit*>(ui->spreadsheetview->findChild<QLineEdit*>());
    if (editor) {
        editor->setCursorPosition(5); // 将光标定位到 "=SUM(|)" 的竖线位置
    }
}
//选择AVERAGE函数
void SpreadsheetWindow::insertAverageFormula()
{
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (!current.isValid()) return;
    // 插入公式
    spreadsheetmodel->setData(current, "=AVERAGE()", Qt::EditRole);
    // 进入编辑模式，光标定位到括号内
    ui->spreadsheetview->edit(current);
    QLineEdit *editor = qobject_cast<QLineEdit*>(ui->spreadsheetview->findChild<QLineEdit*>());
    if (editor) {
        editor->setCursorPosition(9); // 将光标定位到 "=SUM(|)" 的竖线位置
    }
}
//选择MAX函数
void SpreadsheetWindow::insertMaxFormula()
{
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (!current.isValid()) return;
    // 插入公式
    spreadsheetmodel->setData(current, "=MAX()", Qt::EditRole);
    // 进入编辑模式，光标定位到括号内
    ui->spreadsheetview->edit(current);
    QLineEdit *editor = qobject_cast<QLineEdit*>(ui->spreadsheetview->findChild<QLineEdit*>());
    if (editor) {
        editor->setCursorPosition(5); // 将光标定位到 "=SUM(|)" 的竖线位置
    }

}
//选择MIN函数
void SpreadsheetWindow::insertMinFormula()
{
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (!current.isValid()) return;
    // 插入公式
    spreadsheetmodel->setData(current, "=MIN()", Qt::EditRole);
    // 进入编辑模式，光标定位到括号内
    ui->spreadsheetview->edit(current);
    QLineEdit *editor = qobject_cast<QLineEdit*>(ui->spreadsheetview->findChild<QLineEdit*>());
    if (editor) {
        editor->setCursorPosition(5); // 将光标定位到 "=SUM(|)" 的竖线位置
    }
}
//键入公式
void SpreadsheetWindow::TypeFormula()
{
    QModelIndex current = ui->spreadsheetview->currentIndex();
    if (!current.isValid()) return;
    // 插入公式
    spreadsheetmodel->setData(current, "=", Qt::EditRole);
    // 进入编辑模式，光标定位到括号内
    ui->spreadsheetview->edit(current);
    QLineEdit *editor = qobject_cast<QLineEdit*>(ui->spreadsheetview->findChild<QLineEdit*>());
    if (editor) {
        editor->setCursorPosition(1); // 将光标定位到 "=SUM(|)" 的竖线位置
    }
}

/*UI交互*/
//右键显示菜单
void SpreadsheetWindow::showContextMenu(const QPoint &pos)
{
    QMenu menu(this);

    //复制 粘贴 剪切
    menu.addAction(ui->actionCopy);
    menu.addAction(ui->actionPaste);

    menu.addAction(ui->actionCut);
    menu.addSeparator();//分割线

    // 插入
    menu.addMenu(ui->menuInsert);
    // 删除
    menu.addMenu(ui->menuDelete);
    //清除内容
    menu.addAction(ui->actionClear);
    menu.addSeparator();//分割线

    //排序
    menu.addMenu(ui->menuSort);
    //统计计算
    menu.addMenu(ui->menuCalculate);
    //公式
    menu.addMenu(ui->menuFormula);

    // 显示菜单
    menu.exec(pos);
}
//关于软件说明
void SpreadsheetWindow::aboutSpreadSheet()
{
    QString version = "1.0";
    QString buildDate = QString(__DATE__);

    // 创建自定义对话框而不是使用QMessageBox
    QDialog aboutDialog(this);
    aboutDialog.setWindowTitle(tr("关于 Spreadsheet"));
    aboutDialog.setMinimumSize(820, 500);

    // 主布局
    QHBoxLayout *mainLayout = new QHBoxLayout(&aboutDialog);

    // 左侧图标区域
    QLabel *iconLabel = new QLabel;
    QPixmap icon;
    if(icon.load(":/new/prefix1/appicon.ico")) {
        iconLabel->setPixmap(icon.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    } else {
        iconLabel->setPixmap(QApplication::windowIcon().pixmap(128, 128));
    }
    iconLabel->setAlignment(Qt::AlignCenter);

    // 右侧文本区域
    QTextBrowser *textBrowser = new QTextBrowser;
    textBrowser->setOpenExternalLinks(true);
    textBrowser->setTextInteractionFlags(Qt::TextBrowserInteraction);

    QString aboutText =
        QString("<div style='margin: 10px;'>"
                "<h1 style='color: #2a5caa;'>%1</h1>"
                "<h2 style='color: #555;'>%2 %3</h2>"
                "<p><b>%4</b> %5</p>"
                "<p>%6</p>"
                "<hr>"
                "<h3 style='color: #2a5caa;'>%7</h3>"
                "<p>%8</p>"
                "<h3 style='color: #2a5caa;'>%9</h3>"
                "<ul style='margin-left: 20px;'>"
                "<li><b>%10</b>: %11</li>"
                "<li><b>%12</b>: %13</li>"
                "<li><b>%14</b>: %15</li>"
                "<li><b>%16</b>: %17</li>"
                "<li><b>%18</b>: %19</li>"
                "</ul>"
                "<h3 style='color: #2a5caa;'>%20</h3>"
                "<p>%21: 202330451661@mail.scut.edu.cn</p>"
                "<p>%22: <a href='https://gitee.com/int_Tian/spread-sheet' style='color: #2a5caa;'>gitee.com/int_Tian/spread-sheet</a></p>"
                "</div>")
            .arg(tr("Spreadsheet 电子表格软件"))
            .arg(tr("版本")).arg(version)
            .arg(tr("构建日期:")).arg(buildDate)
            .arg(tr("版权所有 © 2025 SCUT/Tian"))
            .arg(tr("软件概述"))
            .arg(tr("Spreadsheet是一款功能强大的电子表格应用程序，支持文件管理、数据编辑、统计计算、公式计算等多种功能。"))
            .arg(tr("主要功能"))
            .arg(tr("文件管理")).arg(tr("新建、打开、保存、另存为、关闭文件"))
            .arg(tr("数据编辑")).arg(tr("复制/粘贴/剪切、插入/删除行列、清除内容、排序"))
            .arg(tr("统计计算")).arg(tr("合计、平均值、最大值、最小值"))
            .arg(tr("公式计算")).arg(tr("插入函数(SUM/AVERAGE/MAX/MIN)、自定义公式"))
            .arg(tr("其他功能")).arg(tr("行列自动扩展、撤销/重做、右键快捷菜单"))
            .arg(tr("技术支持"))
            .arg(tr("邮箱"))
            .arg(tr("官网"));

    textBrowser->setHtml(aboutText);

    // 底部按钮
    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
    connect(buttonBox, &QDialogButtonBox::accepted, &aboutDialog, &QDialog::accept);

    // 右侧文本和按钮的垂直布局
    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(textBrowser);
    rightLayout->addWidget(buttonBox);

    // 添加控件到主布局
    mainLayout->addWidget(iconLabel, 0, Qt::AlignTop);
    mainLayout->addLayout(rightLayout, 1); // 文本区域占据剩余空间

    // 设置样式
    aboutDialog.setStyleSheet(
        "QDialog { background-color: white; }"
        "QTextBrowser { border: none; background: transparent; }"
        "QLabel { margin: 10px; }"
        "QPushButton { min-width: 80px; padding: 5px; }"
        );

    aboutDialog.exec();
}
// 关闭事件
void SpreadsheetWindow::closeEvent(QCloseEvent *event)
{
    if (maybeSave()) {
        settings.sync();  // 确保设置被保存
        event->accept();
    } else {
        event->ignore();
    }
}


